package bb.lanxing.network;

import bb.lanxing.App;
import bb.lanxing.network.AbsResponse;
import bb.lanxing.network.NetSubscribe;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import okhttp3.Call;
import rx.Observable;
import rx.Subscriber;

public class NetOnSubscribe {


    public static class Builder {
        private Call call;
        private Map<String, Object> params = new HashMap();

        public Builder(Call call) {
            this.call = call;
        }

        public Builder append(String str, Object obj) {
            this.params.put(str, obj);
            return this;
        }

        public Observable.OnSubscribe<Response> build() {
            if (this.params.isEmpty()) {
                return new NetResponseOnSubscribe(this.call);
            }
            return new NetResponseOnSubscribe(this.call, this.params);
        }

        public Observable.OnSubscribe<String> buildString() {
            if (this.params.isEmpty()) {
                return new NetStringOnSubscribe(this.call);
            }
            return new NetStringOnSubscribe(this.call, this.params);
        }
    }


    public static abstract class AbsNetOnSubscribe<T> implements Observable.OnSubscribe<T> {
        private Call mCall;
        protected Map<String, Object> params;

        public abstract T onResult(okhttp3.Response response) throws IOException;

//        @Override
//        public void call(Object obj) {
//            call((Subscriber) ((Subscriber) obj));
//        }

        AbsNetOnSubscribe(Call call) {
            this.mCall = call;
        }

        AbsNetOnSubscribe(Call call, Map<String, Object> map) {
            this.mCall = call;
            this.params = map;
        }

        public final void call(Subscriber<? super T> subscriber) {
            try {
                okhttp3.Response execute = this.mCall.execute();
                if (execute.isSuccessful()) {
                    if (!subscriber.isUnsubscribed() || !this.mCall.isCanceled()) {
                        subscriber.onNext(onResult(execute));
                    }
                } else if (execute.code() == 403) {
                    if (App.getContext().isUserSignin()) {
                        App.getContext().cleanSigninState();
                    }
                    App.getContext().userSignin();
                } else if (execute.code() == 504) {
                    throw new NetSubscribe.ApiException(504, "获取数据失败,请检查网络连接");
                } else {
                    NetSubscribe.ApiException.checkResponseThrow(execute.code(), execute.body().string());
                }
                subscriber.onCompleted();
            } catch (IOException | IllegalStateException e) {
                subscriber.onError(e);
            }
        }
    }

    public static class NetStringOnSubscribe extends AbsNetOnSubscribe<String> {
        NetStringOnSubscribe(Call call) {
            super(call);
        }

        NetStringOnSubscribe(Call call, Map<String, Object> map) {
            super(call, map);
        }

        @Override
        public String onResult(okhttp3.Response response) throws IOException {
            return response.body().string();
        }
    }

    public static class NetResponseOnSubscribe extends AbsNetOnSubscribe<Response> {
        NetResponseOnSubscribe(Call call) {
            super(call);
        }

        NetResponseOnSubscribe(Call call, Map<String, Object> map) {
            super(call, map);
        }

        @Override
        public Response onResult(okhttp3.Response response) {
            AbsResponse.Builder builder = new AbsResponse.Builder(response);
            if (this.params != null && !this.params.isEmpty()) {
                builder.appendAll(this.params);
            }
            return builder.build();
        }
    }
}
